import cv2

# from PyQt5.QtGui import *
# from PyQt5.QtCore import *
# from PyQt5.QtWidgets import *
from PyQt5 import QtGui,QtCore
from PyQt5 import  QtWidgets,QtSql
from PyQt5.QtCore import Qt
import logging
import numpy as np
import cv2

# class MyPixmapItem(QtWidgets.QGraphicsPixmapItem):
#     def __init__(self):
#         super().__init__()
#     def hoverEvent(self,event):
#         logging.info("hover")
#     def hoverMoveEvent(self,event):
#         logging.info(event,dir(event))
#         # # logging.info(self.scenePos())
#         # x = event.x()
#         # y = event.y()
#         # s=self.mapToScene(x,y)
#         # # m11=self.transform().m11()
#         # # logging.info(m11,x,y)
#         # # logging.info(float(x)/m11,float(y)/m11)
#         # logging.info(s.x(),s.y())
#         super().hoverMoveEvent(event)
class GraphicsView(QtWidgets.QGraphicsView):
    moved = QtCore.pyqtSignal(float,float,str)
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent=parent)
        self._zoom = 0
        self._empty = True
        self._photo = QtWidgets.QGraphicsPixmapItem()
        self._photo.setAcceptHoverEvents(True)
        self._scene = QtWidgets.QGraphicsScene(self)
        self._scene.addItem(self._photo)
        self.setScene(self._scene)
        self.setAlignment(Qt.AlignCenter)  # 居中显示
        self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)  # 设置拖动
        # self.setDragMode(QGraphicsView.ScrollHandDrag)
        # self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        # hoverMoveEvent()来实现，可通过设置setAcceptHoverEvents(true)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setMinimumSize(640, 480)
        self._photo.hoverMoveEvent = self.hoverMoveEvent
        logging.info(dir(self._photo))
    def hoverMoveEvent(self,event):
        """Show the position, pixel, and value under the mouse cursor.
        """
        # logging.info("hoverEvent")
        if self.has_photo():
            pos = event.pos()
            i, j = pos.y(), pos.x()
            i = int(np.clip(i, 0, self.data.shape[0] - 1))
            j = int(np.clip(j, 0, self.data.shape[1] - 1))
            val = self.data[i, j]
            # ppos = self._photo.mapToParent(pos)
            # x, y = ppos.x(), ppos.y()
            # logging.info(i,j,val)
            self.moved.emit(i,j,str(val))
        # super().hoverMoveEvent(event)
    def contextMenuEvent(self, event):
        if not self.has_photo():
            return
        menu = QtWidgets.QMenu()
        save_action = QtWidgets.QAction('另存为', self)
        save_action.triggered.connect(self.save_current)  # 传递额外值
        menu.addAction(save_action)
        menu.exec(QtGui.QCursor.pos())

    def save_current(self):
        file_name = QtWidgets.QFileDialog.getSaveFileName(self, '另存为', './', 'Image files(*.jpg *.gif *.png)')[0]
        logging.debug(file_name)
        if file_name:
            self._photo.pixmap().save(file_name)

    def get_image(self):
        if self.has_photo():
            return self._photo.pixmap().toImage()

    def has_photo(self):
        return not self._empty

    def change_image(self, img):
        self.update_image(img)
        self.fitInView()

    def img_to_pixmap(self, img):
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # bgr -> rgb
        self.data=img
        h, w, c = img.shape  # 获取图片形状
        image = QtGui.QImage(img, w, h, 3 * w, QtGui.QImage.Format_RGB888)
        return  QtGui.QPixmap.fromImage(image)

    def update_image(self, img):
        self._empty = False
        self._photo.setPixmap(self.img_to_pixmap(img))

    def fitInView(self, scale=True):
        # return
        rect = QtCore.QRectF(self._photo.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
            if self.has_photo():
                unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
                self.scale(1 / unity.width(), 1 / unity.height())
                viewrect = self.viewport().rect()
                scenerect = self.transform().mapRect(rect)
                factor = min(viewrect.width() / scenerect.width(),
                             viewrect.height() / scenerect.height())
                self.scale(factor, factor)
            self._zoom = 0
    def print_trans(self,t):
        r=""
        r+=str(t.m11())+","+str(t.m12())+","+str(t.m13())+"\n"
        r+=str(t.m21())+","+str(t.m22())+","+str(t.m23())+"\n"
        r+=str(t.m31())+","+str(t.m32())+","+str(t.m33())+"\n"
        logging.info(r)
    # def mouseMoveEvent(self,event):
    #     # logging.info(self.scenePos())
    #     x = event.x()
    #     y = event.y()
    #     s=self.mapToScene(x,y)
    #     # m11=self.transform().m11()
    #     # logging.info(m11,x,y)
    #     # logging.info(float(x)/m11,float(y)/m11)
    #     self.moved.emit(s.x(),s.y())
    #     super().mouseMoveEvent(event)
    def wheelEvent(self, event):
        if self.has_photo():
            if event.angleDelta().y() > 0:
                factor = 1.25
                self._zoom += 1
            else:
                factor = 0.8
                self._zoom -= 1
            if self._zoom > 0:
                self.scale(factor, factor)
            elif self._zoom == 0:
                self.fitInView()
            else:
                self._zoom = 0
